#include "common.h"


typedef struct 
{
	char * first_word;
	char * second_word;
	int argcount;
	success_t (*func)(FILE * outstream, char ** args);
} dispatcher_t;

dispatcher_t dispatch_table[] = {
	{"AddApplication", NULL, 2, NULL},
	{"RemoveApplication", NULL, 2, NULL},
	{"AddDetails", "Movie", 3, NULL},
	{"AddDetails", "Playlist", 3, NULL},
	{"AddDetails", "Game", 3, NULL},
	{"UsedApplication", NULL, 3, NULL},
	{"AddScoreToGame", NULL, 3, NULL},
	{"Report", "MostPopular", 2, NULL},
	{"Report", "BestPlayer", 2, NULL},
	{"Report", "NotUsed", 1, NULL},
};


int tokenize(char * buf, char ** tokens, int max_tokens)
{
	int i;
	int j = 0;
	bool_t whitespace = TRUE;
	
	for (i = 0; buf[i] != '\0'; i++)
	{
		if (buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n')
		{
			buf[i] = '\0';
			whitespace = TRUE;
		}
		else if (whitespace)
		{
			if (j > max_tokens)
				break;
			tokens[j] = &buf[i];
			j++;
			whitespace = FALSE;
		}
	}
	
	return j;
}

success_t process_file(FILE * instream, FILE * outstream)
{
	char linebuf[MAX_LINE_SIZE];
	char tokens[MAX_TOKENS][MAX_TOKEN_SIZE];
	int cnt;
	
	while (!feof(instream))
	{
		if (fgets(linebuf, MAX_LINE_SIZE, instream) == NULL)
		{
			/* ERROR: error reading stream */
			return FALSE;
		}
		
		/* tokenize line, skip if empty or comment */
		cnt = tokenize(linebuf, tokens, MAX_TOKENS);
		if (cnt == 0)
			continue;
		if (tokens[0][0] == ';')
			continue;
		if (!process_line(cnt, tokens))
			return FALSE;
	}
	
	return TRUE;
}

success_t process_line(int cnt, char ** tokens, FILE * outstream)
{
	const int disp_count = sizeof(dispatch_table) / sizeof(dispatch_table[0]);
	int i, skip;
	
	for (i = 0; i < disp_count; i++)
	{
		skip = 1;
		if (strcmp(tokens[0], dispatch_table[i].first_word) != 0)
			continue;
		if (dispatch_table[i].second_word != NULL)
		{
			skip++;
			if (cnt < 2 || strcmp(tokens[1], dispatch_table[i].second_word) != 0)
				continue;
		}
		if ((cnt - skip) != dispatch_table[i].argcount)
		{
			/* ERROR: wrong number of arguments */
			return FALSE;
		}
		return dispatch_table[i].func(outstream, &tokens[skip]);
	}
	
	/* ERROR: unknown command */
	return FALSE;
}

success_t disp_addapp(FILE * outstream, char ** args)
{
	char * type, * name;
	type = args[0];
	name = args[1];

	return TRUE;
}


